using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using Isis.Helpers.Impl;
using Isis.Helpers.Interfaces;
using Isis.Interfaces;
using Isis.Model;
using Isis.Views;

namespace Isis.Controllers
{
    public class CacheController : IControlPanelController
    {
        private readonly string _basePath;
        private readonly ITableRenderingHelper _tableRenderingHelper;
        private readonly ICacheWrapper _cacheWrapper;

        public CacheController(string basePath)
        {
            _basePath = basePath;
            _tableRenderingHelper = new TableRenderingHelper();
            _cacheWrapper = new CacheWrapper();
        }

        public void Render(TextWriter writer)
        {
            var pageLayoutWriter = new PageLayoutWriter(Tab.Title, Action, new ControllerRepository(), _basePath);
            pageLayoutWriter.RenderPage(writer, RenderContent);
        }

        private void RenderContent(TextWriter writer)
        {
            switch (Action)
            {
                case "delete": // TODO: should be POST; GET requests should be idempotent
                    if (string.IsNullOrEmpty(Parameter))
                    {
                        HandleAndRenderDelete(writer);
                    }
                    else
                    {
                        HandleAndRenderDeleteItem(writer, Parameter);
                    }
                    break;
                case "output_cache":
                    RenderOutputCache(writer);
                    break;
                default: // "cache"
                    RenderDefault(writer);
                    break;
            }
        }

        private void RenderOutputCache(TextWriter writer)
        {
            throw new NotImplementedException();
        }

        private void RenderDefault(TextWriter writer)
        {
            RenderCacheStatsSection(writer);

            RenderCacheItemsTable(writer);

            writer.Write("<br />");
            writer.Write("<br />");

            RenderRefreshPageButton(writer);
        }

        private void RenderRefreshPageButton(TextWriter writer)
        {
            writer.Write("<a href=/isis/cache>Refresh Page</a>");
        }

        private void RenderCacheStatsSection(TextWriter writer)
        {
            writer.Write(string.Format("<p>Number of cache items: {0}</p>", _cacheWrapper.GetCacheCount()));
            writer.Write(string.Format("<p>Maximum cache memory usage: {0} Mb</p>", _cacheWrapper.GetMaxCacheMemory()));
            writer.Write(string.Format("<p>Maximum percentage cache memory usage: {0:P}</p>", _cacheWrapper.GetMaxCacheMemoryPercentage()));
        }

        private void RenderDeleteAllCacheItems(TextWriter writer)
        {
            writer.Write("<script LANGUAGE=\"JavaScript\">function confirmDeleteAll(){var agree=confirm(\"Are you sure you want to delete entire contents of cache?\");if(agree) return true; else return false;}</script>");
            writer.Write("<a onclick=\"return confirmDeleteAll()\" href=\"/isis/cache/delete\">Delete all cache entries</a>");
        }

        private void RenderCacheItemsTable(TextWriter writer)
        {
            IDictionary<string, object> cacheItems = _cacheWrapper.GetCacheItems();

            if (!cacheItems.Any()) return;

            writer.Write("<script type=\"text/javascript\">function confirmDeleteLink(cachekey){var agree=confirm(\"Are you sure you want to delete \" + cachekey + \"?\");if(agree) return true; else return false;}</script>");

            writer.Write(_tableRenderingHelper.RenderTableHeader("Cache Items"));
            writer.Write(_tableRenderingHelper.RenderHeaderRow(new[] { "Cache Key", "Cached Object Type", "View Data", "Action" }));

            foreach (KeyValuePair<string, object> cacheItem in cacheItems)
            {
                var cellsInRow = new[]
                {
                    cacheItem.Key, 
                    cacheItem.Value.GetType().FullName,
                    cacheItem.Value.ToString(),
                    RenderDeleteCacheItemLink(cacheItem.Key)
                };
                writer.Write(_tableRenderingHelper.RenderRow(cellsInRow));
            }

            writer.Write("</table>");
            RenderDeleteAllCacheItems(writer);
        }

        private string RenderDeleteCacheItemLink(string key)
        {
            return string.Format("<a onclick=\"return confirmDeleteLink('{0}')\" href=\"/isis/cache/delete/{0}\">Delete</a>", key);
        }

        private void HandleAndRenderDelete(TextWriter writer)
        {
            _cacheWrapper.ClearCache(HttpRuntime.Cache);

            RenderDefault(writer);
        }        

        private void HandleAndRenderDeleteItem(TextWriter writer, string cacheItemKey)
        {
            HttpContext.Current.Cache.Remove(cacheItemKey);

            RenderDefault(writer);
        }

        public ControllerTab Tab
        {
            get { return new ControllerTab("Cache"); }
        }

        public string Action { get; set; }

        public string Parameter { get; set; }

        public IEnumerable<string> SubTabs
        {
            get { return new[] { "Cache", "Output Cache" }; }
        }
    }
}